package com.tengfei.blogsystem.service.impl;

import com.tengfei.blogsystem.dao.ArticleDao;
import com.tengfei.blogsystem.dao.ArticleNoContentDao;
import com.tengfei.blogsystem.pojo.Article;
import com.tengfei.blogsystem.pojo.ArticleNoContent;
import com.tengfei.blogsystem.pojo.User;
import com.tengfei.blogsystem.response.ResponseResult;
import com.tengfei.blogsystem.response.ResponseState;
import com.tengfei.blogsystem.service.IArticleService;
import com.tengfei.blogsystem.service.IUserService;
import com.tengfei.blogsystem.utils.Constants;
import com.tengfei.blogsystem.utils.SnowFlakeIdWorker;
import com.tengfei.blogsystem.utils.TextUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @version v1.0
 * @author} feige
 * @date 2021-10-28-19:27
 * @description
 */
@Service
@Transactional
public class ArticleServiceImpl implements IArticleService {

    @Autowired
    private SnowFlakeIdWorker idWorker;
    @Autowired
    private IUserService userService;
    @Autowired
    private ArticleDao articleDao;
    @Autowired
    private ArticleNoContentDao articleNoContentDao;

    @Override
    public ResponseResult postArticle(Article article, HttpServletRequest request, HttpServletResponse response) {
        // 获取当前用户
        User user = userService.checkUser(request, response);
        if (user == null) {
            return new ResponseResult(ResponseState.NOT_LOGIN);
        }
        // 检查数据
        String title = article.getTitle();
        if (TextUtils.isEmpty(title)) {
            return new ResponseResult(ResponseState.ERROR, "文章标题不能为空");
        }
        if (title.length() > Constants.Article.TITLE_MAX_LENGTH) {
            return new ResponseResult(ResponseState.ERROR, "文章标题长度不可以超过" + Constants.Article.TITLE_MAX_LENGTH + "个字符");
        }
        // 提交类型
        String state = article.getState();
        if (!Constants.Article.STATE_PUBLISH.equals(state) && !Constants.Article.STATE_DRAFT.equals(state)) {
            return new ResponseResult(ResponseState.ERROR, "不支持这种类型");
        }
        String categoryId = article.getCategoryId();
        if (TextUtils.isEmpty(categoryId)) {
            return new ResponseResult(ResponseState.ERROR, "文章分类id不能为空");
        }
        String content = article.getContent();
        if (TextUtils.isEmpty(content)) {
            return new ResponseResult(ResponseState.ERROR, "文章内容不能为空");
        }
        String type = article.getType();
        if (TextUtils.isEmpty(type)) {
            return new ResponseResult(ResponseState.ERROR, "文章类型不能为空");
        }
        String summary = article.getSummary();
        if (TextUtils.isEmpty(summary)) {
            return new ResponseResult(ResponseState.ERROR, "文章摘要不能为空");
        }
        if (summary.length() > Constants.Article.SUMMARY_MAX_LENGTH) {
            return new ResponseResult(ResponseState.ERROR, "文章摘要长度不可以超过" + Constants.Article.SUMMARY_MAX_LENGTH + "个字符");
        }
        String labels = article.getLabels();
        if (TextUtils.isEmpty(labels)) {
            return new ResponseResult(ResponseState.ERROR, "文章标签不能为空");
        }


        String articleId = article.getId();
        if (TextUtils.isEmpty(articleId)) {
            // 新建文章
            // 补充数据
            article.setId(String.valueOf(idWorker.nextId()));
            article.setCreateTime(new Date());

        } else {
            // 更新文章
            Article articleById = articleDao.findOneById(articleId);
            if (Constants.Article.STATE_PUBLISH.equals(articleById.getState())) {
                // 已发布
                return new ResponseResult(ResponseState.ERROR, "文章已发布，不支持草稿保存");
            }
        }
        article.setUserId(user.getId());
        article.setUpdateTime(new Date());
        // 保存到数据库
        articleDao.save(article);
        return new ResponseResult(ResponseState.SUCCESS, "保存成功");
    }

    @Override
    public ResponseResult listArticle(int page, int size, String state, String keywords, String categoryId) {
        // 分页
        // 分页查询
        if (page < Constants.PageValue.DEFAULT_PAGE) {
            page = Constants.PageValue.DEFAULT_PAGE;
        }
        if (size < Constants.PageValue.MIN_SIZE) {
            size = Constants.PageValue.MIN_SIZE;
        }
        // 排序
        Sort sort = Sort.by(Sort.Direction.DESC, "createTime");
        Pageable pageable = PageRequest.of(page - 1, size, sort);
        // 查询
        Page<ArticleNoContent> articles = articleNoContentDao.findAll(new Specification<ArticleNoContent>() {
            @Override
            public Predicate toPredicate(Root<ArticleNoContent> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                // 判断是否有传参数
                if (!TextUtils.isEmpty(state)) {
                    Predicate statePre = cb.equal(root.get("state").as(String.class), state);
                    list.add(statePre);
                }
                if (!TextUtils.isEmpty(keywords)) {
                    Predicate keywordsPre = cb.like(root.get("title").as(String.class), "%" + keywords + "%");
                    list.add(keywordsPre);
                }
                if (!TextUtils.isEmpty(categoryId)) {
                    Predicate categoryIdPre = cb.equal(root.get("categoryId").as(String.class), categoryId);
                    list.add(categoryIdPre);
                }
                Predicate[] preList = new Predicate[list.size()];
                list.toArray(preList);
                return cb.and(preList);
            }
        }, pageable);
        return new ResponseResult(ResponseState.SUCCESS, "查询成功", articles);
    }


    @Override
    public ResponseResult getArticle(String articleId, HttpServletRequest request,
                                     HttpServletResponse response) {
        // 查询文章
        Article articleById = articleDao.findOneById(articleId);
        if (articleById == null) {
            return new ResponseResult(ResponseState.ERROR, "文章不存在");
        }
        // 判断文章状态
        String state = articleById.getState();
        if (Constants.Article.STATE_TOP.equals(state) || Constants.Article.STATE_PUBLISH.equals(state)) {
            return new ResponseResult(ResponseState.SUCCESS, "查询文章成功", articleById);
        }
        // 如果是草稿，需要管理员权限
        User user = userService.checkUser(request, response);
        if (!user.getRoles().equals(Constants.User.ROLE_ADMIN)) {
            return new ResponseResult(ResponseState.NO_PERMISSION);
        }
        return new ResponseResult(ResponseState.SUCCESS, "获取文章成功", articleById);
    }
}
